/**
 * 本地缓存程序处理
 * 2017年12月26日 星期二
 */

/**----------------------新扩展--------------------------2016年8月30日 星期二>>  				类似数据库处理操作// js面向对象式编程
 *	engine 引擎|| session/local，默认前者
 *	add()		插入数据到storage内，会覆盖历史数据
 *	update()	更新数据到storage内，支持 json/string，可实现删除内部数据
 *	select()	storage数据获取
 *	get()		简单数据获取法
 *
 *	table()		get/set storage数据键名
 *	error()		get/set storage数据异常
 *	session()/local()	storage数据设置获取函数(原型)
 *	undefind()	数据格式检测
 *	object(),empty()
 */

class jutilStorage{
    /**
     * @param {string|null} engine 
     */
    constructor(engine){
        if('session' != engine && 'local' != engine) this.engine = 'session';
        else this.engine = engine;
    }
    /**
     * @param {string} tb 
     */
    table(tb){
        if(this.undefind(tb)){
            var table = this._table;
            if(this.undefind(table)) this._table = '';
            return this._table;
        }else{
            this._table = tb;
            return this; // 链式数据处理
        }
    }
    /**
     * 会覆盖原来的值，若存在原来的json数据/JSON
     * @param {Object} data 
     * @param {string} table 
     */
    add(data,table){
        if(this.empty(table)) table = this.table();
        if(this.empty(table)){
            this.error('add## 无法获取到table的值！');
            return '';
        }
        if(!this.object(data)){
            this.error('add## 存储数据必须为JSON格式数据！');
            return '';
        }
        var str = JSON.stringify(data);
        if(this.engine == 'session') this.session(table,str);
        else this.local(table,str);
        return true;
    }
    /**
     * 更新数据/可更新不存在的数据
     * @param {string} key 
     * @param {*} value 
     */
    update(key,value){
        var tb = this.table();
        if(this.empty(tb)){
            this.error('select## 无法获取到table的值！');
            return false;
        }
        var data = this.select();
        if(this.empty(key)){
            this.error('update## 无法获取到key的值,请设置key（json/string）值！');
            return false;
        }
        if(!this.object(data)) data = {};
        if(this.object(key)){
            for(var k in key){data[k] = key[k];}
        }
        if(this.undefind(value)){
            delete data[key];
        }else{
            data[key] = value;
        }
        var str = JSON.stringify(data);
        return this.engine == 'session'? this.session(tb,str):this.local(tb,str);
    }
    select(key,value){
        var tb = this.table();
        if(this.empty(tb)){
            this.error('select## 无法获取到table的值！');
            return '';
        }
        var str = this.engine == 'session'? this.session(tb):this.local(tb);
        var data = {};
        try{
            data = JSON.parse(str);
        }catch(e){
            this.error(e);
        }
        if(this.empty(key)) return data;//	返回整个json数据
        else if(this.undefind(value)){//	返回单个json数据
            if(!this.empty(data) && data[key]) return data[key];
            return null;
        }
        data[key] = value;//	设置json的属性值
    }
    /**
     * 获取值
     * @param {string} key 
     * @param {any} def
     * @return {any} 
     */
    get(key, def){
        def = def || null;
        var value = this.select(key);
        return value || def;
        // return null === value? def: value;
    }
    /**
     * 分隔符解析数组
     */
    array(key,value,delimiter){
        if(this.empty(key)) return;
        delimiter = delimiter? delimiter:',';
        if(this.undefind(value)){// 获取值
            var tmp = this.get(key);
            if(tmp) return tmp.split(delimiter);
            return;
        }
        if(this.empty(value)) return;
        var tmp = this.get(key);
        if(tmp.indexOf(value) == -1){
            var arr = tmp.split(delimiter);
            arr.push(value);
            this.update(key,arr.join(delimiter));
        }
    }
    /**
     * 函数分隔符数组中指定的属性值
     * @param {*} key 
     * @param {*} value 
     * @param {*} delimiter 
     */
    removeArray(key,value,delimiter){
        var arr = this.array(key);
        var newArr = new Array();
        for(var i=0; i<arr.length; i++){
            if(arr[i] == value) continue;
            newArr.push(arr[i]);
        }
        delimiter = delimiter? delimiter:',';
        return this.update(key,newArr.join(delimiter));
    }
    undefind(value){
        if(typeof(value) == 'undefind') return true;
        else if(value == null) return true;
        return false;
    }
    object(data){
        if(null == data) return false;
        if(typeof(data) == 'object') return true;
        return false;
    }
    empty(value){
        if(this.undefind(value)) return true;
        else if(value == '') return true;
        else if(value == 0) return true;
        return false;
    }
    session(name,value)
    {
        if(this.undefind(window.sessionStorage)){this.error('浏览器不支持 sessionStorage');}
        if(this.empty(name)) return null;
        if(this.empty(value))	return sessionStorage.getItem(name);
        sessionStorage.setItem(name,value);
        return true;
    }
    /**
     * loaclstroge 本地存储	2016/4/8
     * @param {*} name 
     * @param {*} value 
     */
    local(name,value)
    {
        if(this.undefind(window.localStorage)){this.error('浏览器不支持 localStorage');}
        if(this.empty(name)) return false;
        if(this.empty(value))	return localStorage.getItem(name);
        localStorage.setItem(name,value);
        return true;
    }
    /**
     * 删除storage
     * @param {*} tb 
     */
    delete(tb){
        tb = tb || this._table;
        if(this.empty(tb)) return false;
        if(engine == 'local'){
            if(localStorage.getItem(tb)){
                localStorage.removeItem(tb);
                return true;
            }
        }
        else if(sessionStorage.getItem(td)){
            sessionStorage.removeItem(td);
            return true;
        }
        return false;
    }
    /**
     * 
     * @param {*} err 
     */
    error(err){
        if(this.undefind(err)){
            var message = this._error;
            if(this.undefind(message)) this._error = '0';
            //	浏览器自动调试输出
            try{console.log(this._error)}catch(e){}
            return this._error;
        }else this._error = err;
    }
    is_string(value){
        if(typeof value == 'string') return true;
        return flase;
    }
    is_object(value){
        if(typeof value == 'object') return true;
        return flase;
    }
}

export default jutilStorage